from vtk import *
class Drawer:
    def __init__(self,lattice,vertex,vertex_inv,source_view,target_view,g):
        self.g = g
        self.maxlev = lattice.GetNumberOfLevels()
        self.lattice = lattice
        self.vertex = vertex
        self.vertex_inv = vertex_inv
        self.view = source_view
        self.view2 = target_view
            

    def fetch_close_concepts(self,caller, event):
        #print "Searching subgraph..."
        sel = caller.GetCurrentSelection()
        
        node0 = sel.GetNode(1)
        
        if node0.GetFieldType() == 3:
            sl = node0.GetSelectionList()
            if sl.GetNumberOfTuples() < 1:
                print "No concept selected"
                return
            elif sl.GetNumberOfTuples() > 1:
                print "Please, select just one concept"
                return
        else:
            print "No node selected"
            return
        
        x = node0.GetSelectionList().GetValue(0)
        print self.lattice.GetConcept(self.vertex_inv[x]).Summary()
        bfs = vtkBoostBreadthFirstSearch()
        bfs.AddInputConnection(self.g.GetProducerPort())
        bfs.SetOriginVertex(x)
        
        cutter = vtkSelectionSource()
        cutter.SetContentType(7)
        cutter.SetFieldType(3)
        cutter.SetArrayName("BFS")
        cutter.AddThreshold(0,100)
        cutter.Update()
        
        extract_graph = vtkExtractSelectedGraph()
        extract_graph.AddInputConnection(bfs.GetOutputPort())
        extract_graph.SetSelectionConnection(cutter.GetOutputPort())
        extract_graph.Update()
        
        
        sels = vtkIdTypeArray()
        edges = vtkIdTypeArray() 
        
        cat = vtkVertexListIterator()
        pedy = extract_graph.GetOutput().GetVertexData().GetPedigreeIds()
        extract_graph.GetOutput().GetVertices(cat)
        while cat.HasNext():
            a = cat.Next()
            joint = self.lattice.GetConcept(self.vertex_inv[pedy.GetValue(a)])
            for p in joint.GetParents():
                newid = extract_graph.GetOutput().AddVertex()
                #extract_graph.GetOutput().GetVertexData().GetPedigreeIds().InsertValue(newid,self.vertex[p.GetId()])
                #extract_graph.GetOutput().GetVertexData().GetArray("names").InsertValue(newid,"caca")
                print self.vertex[p.GetId()]
                sels.InsertNextValue(pedy.GetValue(self.vertex[p.GetId()]))
            sels.InsertNextValue(pedy.GetValue(a))

        extract_graph.Update()

        self.view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
        self.view2.GetRepresentation(0).SetSelectionType(2)
        self.view2.SetLayoutStrategyToPassThrough()

        self.g.GetInducedEdges(sels,edges)
        
        node0.SetSelectionList(sels)
        sel.GetNode(0).SetSelectionList(edges)
        sel.Update()
        
        self.view2.ResetCamera()
        self.view2.Render()
    #print "Subgraph search ended"
    
            
    def selectionCallback3(self,caller, event):
        #print "Searching subgraph..."
        sel = caller.GetCurrentSelection()
        
        node0 = sel.GetNode(1)
        
        if node0.GetFieldType() == 3:
            sl = node0.GetSelectionList()
            if sl.GetNumberOfTuples() < 1:
                print "No concept selected"
                return
            elif sl.GetNumberOfTuples() > 1:
                print "Please, select just one concept"
                return
        else:
            print "No node selected"
            return
        
        x = node0.GetSelectionList().GetValue(0)
        print self.lattice.GetConcept(self.vertex_inv[x]).Summary()
        
        # GET THE SUBHIERARCHY OF THE SELECTED CONCEPT
        bfs = vtkBoostBreadthFirstSearch()
        bfs.AddInputConnection(self.g.GetProducerPort())
        bfs.SetOriginVertex(x)
        
        # CREATE THE SELECTOR OF THE SUBHIERARCHY
        cutter = vtkSelectionSource()
        cutter.SetContentType(7)
        cutter.SetFieldType(3)
        cutter.SetArrayName("BFS")
        cutter.AddThreshold(0,100)
        cutter.Update()
        
        # CREATE THE SUBGRAPH WITH TH SUBHIERARCHY
        extract_graph = vtkExtractSelectedGraph()
        extract_graph.AddInputConnection(bfs.GetOutputPort())
        extract_graph.SetSelectionConnection(cutter.GetOutputPort())
        extract_graph.Update()
        
            
        # LOOK FOR THE CLOSE CONCEPTS
        sels = vtkIdTypeArray()
        edges = vtkIdTypeArray()
        types = vtkIntArray()
        types.SetName("size")
        
        cat = vtkVertexListIterator()
        pedy = extract_graph.GetOutput().GetVertexData().GetPedigreeIds()
        extract_graph.GetOutput().GetVertices(cat)
        while cat.HasNext():
            a = cat.Next()
            sels.InsertNextValue(pedy.GetValue(a))
            joint = self.lattice.GetConcept(self.vertex_inv[pedy.GetValue(a)])
            types.InsertValue(a,1)
            if self.vertex_inv[x] != joint.GetId() and joint.type != 'bottom':
                print self.vertex_inv[x],joint.GetId()
                for p in joint.GetParents():
                    #newid = extract_graph.GetOutput().AddVertex()
                    #extract_graph.GetOutput().GetVertexData().GetPedigreeIds().InsertValue(newid,self.vertex[p.GetId()])
                    #extract_graph.GetOutput().GetVertexData().GetArray("names").InsertValue(newid,"caca")
                    print self.vertex[p.GetId()],pedy.GetValue(self.vertex[p.GetId()])
                    types.InsertValue(self.vertex[p.GetId()],5)
                    sels.InsertNextValue(self.vertex[p.GetId()])
        
        self.g.GetInducedEdges(sels,edges)
        
        node0.SetSelectionList(sels)
        print caller
        sel.GetNode(0).SetSelectionList(edges)
        sel.Update()
        
        cutter2 = vtkSelectionSource()
        cutter2.SetContentType(vtkSelectionNode.INDICES)
        cutter2.SetFieldType(vtkSelectionNode.VERTEX)
        for i in range(sels.GetNumberOfTuples()):
            cutter2.AddID(0,sels.GetValue(i))
        cutter2.Update()
        
                        
        extract_graph2 = vtkExtractSelectedGraph()
        extract_graph2.AddInputConnection(self.g.GetProducerPort())
        extract_graph2.SetSelectionConnection(cutter2.GetOutputPort())
        extract_graph2.GetOutput()
        extract_graph2.Update()
                
        #g2.GetVertexData().AddArray(types)

#        self.view2.AddRepresentationFromInput(extract_graph2.GetOutput())
        self.view2.AddRepresentationFromInputConnection(g2.GetProducerPort())
        self.view2.GetRepresentation(0).SetSelectionType(2)
        self.view2.SetLayoutStrategyToPassThrough()
        self.view2.ResetCamera()
        self.view2.Render()
    #print "Subgraph search ended"
    
    def select_close_concepts(self,caller, event):
        #print "Searching subgraph..."
        sel = caller.GetCurrentSelection()
        
        node0 = sel.GetNode(1)
        
        if node0.GetFieldType() == 3:
            sl = node0.GetSelectionList()
            if sl.GetNumberOfTuples() < 1:
                print "No concept selected"
                return
            elif sl.GetNumberOfTuples() > 1:
                print "Please, select just one concept"
                return
        else:
            print "No node selected"
            return
        
        x = node0.GetSelectionList().GetValue(0)
        print self.lattice.GetConcept(self.vertex_inv[x]).Summary()
        bfs = vtkBoostBreadthFirstSearch()
        bfs.AddInputConnection(self.g.GetProducerPort())
        bfs.SetOriginVertex(x)
        
        cutter = vtkSelectionSource()
        cutter.SetContentType(7)
        cutter.SetFieldType(3)
        cutter.SetArrayName("BFS")
        cutter.AddThreshold(0,100)
        cutter.Update()
        
        extract_graph = vtkExtractSelectedGraph()
        extract_graph.AddInputConnection(bfs.GetOutputPort())
        extract_graph.SetSelectionConnection(cutter.GetOutputPort())
        
        extract_graph.Update()
        
        sels = vtkIdTypeArray()
        edges = vtkIdTypeArray() 
        
        cat = vtkVertexListIterator()
        pedy = extract_graph.GetOutput().GetVertexData().GetPedigreeIds()
        extract_graph.GetOutput().GetVertices(cat)
        while cat.HasNext():
            a = cat.Next()
            sels.InsertNextValue(pedy.GetValue(a))
            joint = self.lattice.GetConcept(self.vertex_inv[pedy.GetValue(a)])
            if self.vertex_inv[x] != joint.GetId() and joint.type != 'bottom':
                print self.vertex_inv[x],joint.GetId()
                for p in joint.GetParents():
                    #newid = extract_graph.GetOutput().AddVertex()
                    #extract_graph.GetOutput().GetVertexData().GetPedigreeIds().InsertValue(newid,self.vertex[p.GetId()])
                    #extract_graph.GetOutput().GetVertexData().GetArray("names").InsertValue(newid,"caca")
                    print self.vertex[p.GetId()],pedy.GetValue(self.vertex[p.GetId()])
                    sels.InsertNextValue(self.vertex[p.GetId()])
                        
        self.g.GetInducedEdges(sels,edges)
        
        node0.SetSelectionList(sels)
        sel.GetNode(0).SetSelectionList(edges)
        sel.Update()
        
                
        self.view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
        self.view2.GetRepresentation(0).SetSelectionType(2)
        self.view2.SetLayoutStrategyToPassThrough()
        self.view2.ResetCamera()
        self.view2.Render()
        #print "Subgraph search ended"
            
            
    def selectionCallback2(self,caller, event):
        #print "Searching subgraph..."
        sel = caller.GetCurrentSelection()
        
        node0 = sel.GetNode(1)

        if node0.GetFieldType() == 3:
            sl = node0.GetSelectionList()
            if sl.GetNumberOfTuples() < 1:
                print "No concept selected"
                return
            elif sl.GetNumberOfTuples() > 1:
                print "Please, select just one concept"
                return
        else:
            print "No node selected"
            return

        x = node0.GetSelectionList().GetValue(0)
        print self.lattice.GetConcept(self.vertex_inv[x]).Summary()
        bfs = vtkBoostBreadthFirstSearch()
        bfs.AddInputConnection(self.g.GetProducerPort())
        bfs.SetOriginVertex(x)
        
        cutter = vtkSelectionSource()
        cutter.SetContentType(7)
        cutter.SetFieldType(3)
        cutter.SetArrayName("BFS")
        cutter.AddThreshold(0,100)
        cutter.Update()

        extract_graph = vtkExtractSelectedGraph()
        extract_graph.AddInputConnection(bfs.GetOutputPort())
        extract_graph.SetSelectionConnection(cutter.GetOutputPort())

        self.view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
        self.view2.GetRepresentation(0).SetSelectionType(2)
        self.view2.SetLayoutStrategyToPassThrough()
        extract_graph.Update()
        
        sels = vtkIdTypeArray()
        edges = vtkIdTypeArray() 
        
        cat = vtkVertexListIterator()
        pedy = extract_graph.GetOutput().GetVertexData().GetPedigreeIds()
        extract_graph.GetOutput().GetVertices(cat)
        while cat.HasNext():
            a = cat.Next()
            sels.InsertNextValue(pedy.GetValue(a))
        
        self.g.GetInducedEdges(sels,edges)

        node0.SetSelectionList(sels)
        sel.GetNode(0).SetSelectionList(edges)
        sel.Update()

        self.view2.ResetCamera()
        self.view2.Render()
        #print "Subgraph search ended"
        
    def selectionCallback(self,caller, event):
        fil = vtkIdTypeArray()
        print "Searching subgraph..."

        sel = caller.GetCurrentSelection()
        print sel
        node0 = sel.GetNode(1)
        
        if node0.GetFieldType() == 3:
            sl = node0.GetSelectionList()
            if sl.GetNumberOfTuples() > 0:
                fil.InsertValue(0,sl.GetValue(0))
                parents = self.printChildren(self.vertex_inv[sl.GetValue(0)])
                j = 1
                for p in parents:
                    fil.InsertValue(j, int(self.vertex[p]))
                    j += 1
            else:
                print "No concept selected"
        node0.SetSelectionList(fil)
        node0.SetContentType(vtkSelectionNode.INDICES);
        node0.SetFieldType(vtkSelectionNode.VERTEX);
        
        sel.Update()
        
        extract_graph = vtkExtractSelectedGraph()
        extract_graph.SetInput(0,self.g)
        extract_graph.SetInput(1,sel)
        extract_graph.Update()
        print "EDGES: ",extract_graph.GetOutput().GetNumberOfEdges()
        
        self.view2.AddRepresentationFromInputConnection(extract_graph.GetOutputPort())
        self.view2.SetLayoutStrategyToPassThrough()
        self.view2.ResetCamera()
        self.view2.Render()
        print "Subgraph search ended"
     
    def printFieldType(self,field_type):
           if field_type == 3:
               print "Vertices Selected:"
           elif field_type == 4:
               print "Edges Selected:"
           else:
               print "Unknown type:"

##################################################################
# FUNCTIONS REQUIRED FOR MAC COMPATIBILITY
# press p to toggle panning
# press z to toggle zooming
# press s to toggle select
##################################################################
def keyPress(obj,event):
    int = obj.GetInteractor()
    key = int.GetKeySym()
    if key == 'p':
        obj.RemoveObservers("LeftButtonPressEvent")
        obj.RemoveObservers("LeftButtonReleaseEvent")
        obj.AddObserver("LeftButtonPressEvent",startPan)
        obj.AddObserver("LeftButtonReleaseEvent",endPan)
    if key == 'z':
        obj.RemoveObservers("LeftButtonPressEvent")
        obj.RemoveObservers("LeftButtonReleaseEvent")
        obj.AddObserver("LeftButtonPressEvent",startZoom)
        obj.AddObserver("LeftButtonReleaseEvent",endZoom)
    if key == 's':
        obj.RemoveObservers("LeftButtonPressEvent")
        obj.RemoveObservers("LeftButtonReleaseEvent")
        obj.AddObserver("LeftButtonPressEvent",startSelect)
        obj.AddObserver("LeftButtonReleaseEvent",endSelect)
    obj.OnChar()

def startPan(obj,event):
    #print 'panning'
    obj.OnMiddleButtonDown()
def endPan(obj,event):
    obj.OnMiddleButtonUp()

def startZoom(obj,event):
    #print 'zooming'
    obj.OnRightButtonDown()
def endZoom(obj,event):
    obj.OnRightButtonUp()

def startSelect(obj,event):
    #print 'selecting'
    obj.OnLeftButtonDown()
def endSelect(obj,event):
    obj.OnLeftButtonUp()


